//
//  DaylightMonitor.m
//  Shion
//
//  Created by Chris Karr on 8/13/08.
//  Copyright 2008 Northwestern University. All rights reserved.
//

#import "DaylightMonitor.h"


@implementation DaylightMonitor

@synthesize lastStatus;
@synthesize timer;

- (CGFloat) fractionalYear
{
	NSCalendarDate * now = [NSCalendarDate date];
	
	return ((2 * M_PI) / 365) * (((CGFloat) [now dayOfYear]) - 1 + ((((CGFloat) [now hourOfDay]) - 12) / 24));
}

- (CGFloat) eqTime
{
	CGFloat fractYear = [self fractionalYear];
	
	CGFloat et = 229.18 * (0.000075 + (0.001868 * cos (fractYear)) - (0.032077 * sin (fractYear)) - 
						   (0.014615 * cos (2 * fractYear)) - (0.040849 * sin (2 * fractYear)));
	
	return et;
}

- (CGFloat) solarDeclination
{
	CGFloat fractYear = [self fractionalYear];
	
	CGFloat decl = 0.006918 - (0.399912 * cos (fractYear)) + (0.070257 * sin (fractYear)) - (0.006758 * cos (2 * fractYear)) +
	(0.000907 * sin (2 * fractYear)) - (0.002697 * cos (3 * fractYear)) + (0.00148 * sin (3 * fractYear));
	
	return decl;
}

- (CGFloat) radiansForDegrees:(CGFloat) degrees
{
	return (M_PI / 180.0) * degrees;
}

- (CGFloat) degreesForRadians:(CGFloat) rads
{
	return (180 / M_PI) * rads;
}

- (CGFloat) hourAngleForLatitude:(CGFloat) lat longitude:(CGFloat) lon
{
	CGFloat decl = [self solarDeclination];
	
	CGFloat ha =  acos ((cos ([self radiansForDegrees:90.833]) / (cos ([self radiansForDegrees:lat]) * cos (decl))) - 
						(tan ([self radiansForDegrees:lat]) * tan (decl)));
	
	return ha;
}

- (CGFloat) sunriseForLatitude:(CGFloat) lat longitude:(CGFloat) lon
{
	return 720 + (4 * (lon - [self degreesForRadians:[self hourAngleForLatitude:lat longitude:lon]])) - [self eqTime];
}

- (CGFloat) sunsetForLatitude:(CGFloat) lat longitude:(CGFloat) lon
{
	return 720 + (4 * (lon + [self degreesForRadians:[self hourAngleForLatitude:lat longitude:lon]])) - [self eqTime];
}

- (CGFloat) solarNoonForLatitude:(CGFloat) lat longitude:(CGFloat) lon
{
	return 720 + (4 * lon) - [self eqTime];
}

- (void) awakeFromNib
{
	location = malloc (sizeof (MachineLocation));
	
	self.timer = [NSTimer scheduledTimerWithTimeInterval:60.0 target:self selector:@selector(update:) userInfo:nil repeats:YES];
	// [self.timer fire];
}

- (void) dealloc
{
	[self.timer invalidate];
	self.timer = nil;
	self.lastStatus = nil;
	
	free (location);
	
	[super dealloc];
}

- (void) update:(NSTimer *) theTimer
{
	ReadLocation (location);
	
	NSTimeZone * myTimeZone = [NSTimeZone localTimeZone];
	
	CGFloat latitude = 90 * FractToFloat (location->latitude);
	CGFloat longitude = -90 * FractToFloat (location->longitude);
	
	CGFloat utcSunrise = [self sunriseForLatitude:latitude longitude:longitude] + ([myTimeZone secondsFromGMT] / 60);
	CGFloat utcSunset = [self sunsetForLatitude:latitude longitude:longitude]  + ([myTimeZone secondsFromGMT] / 60);
	
	NSCalendarDate * now = [NSCalendarDate date];
	NSUInteger nowMinutes = ([now hourOfDay] * 60) + [now minuteOfHour];
	
	NSString * timeOfDay = @"Sunset";
	if (nowMinutes > utcSunrise && nowMinutes < utcSunset)
		timeOfDay = @"Sunrise";

	if (self.lastStatus != nil && ![timeOfDay isEqual:self.lastStatus])
		[[NSNotificationCenter defaultCenter] postNotificationName:DAYLIGHT_UPDATE object:self userInfo:[NSDictionary dictionaryWithObject:timeOfDay forKey:@"Event"]];

	self.lastStatus = timeOfDay;
}

@end
